]> dgit.raspbian.org Git - gnome-shell.git/commitdiff
jsParse: Make getCompletions() asynchronous
authorFlorian Müllner <fmuellner@gnome.org>
Wed, 12 Jul 2023 23:52:06 +0000 (01:52 +0200)
committerMarge Bot <marge-bot@gnome.org>
Fri, 14 Jul 2023 12:36:53 +0000 (12:36 +0000)
Part of the possible completions involves evaluating the part
of the passed in text that looks like an object, so that we
can query it for properties.

Using a Function or eval() for that means that we can only
complete text that does not use `await`. To get over that
limitation, evaluate the text in an AsyncFunction instead.

Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/2842>

js/misc/jsParse.js

index 18ce703982a0cf5a91ba99e89efa1f334f5044d6..e55d69a30df12496b19cee181831ac8abfc6254b 100644 (file)
@@ -1,6 +1,8 @@
 /* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */
 /* exported getCompletions, getCommonPrefix, getDeclaredConstants */
 
+const AsyncFunction = async function () {}.constructor;
+
 /**
  * Returns a list of potential completions for text. Completions either
  * follow a dot (e.g. foo.ba -> bar) or they are picked from globalCompletionList (e.g. fo -> foo)
@@ -13,7 +15,7 @@
  * @param {string} commandHeader
  * @param {readonly string[]} [globalCompletionList]
  */
-function getCompletions(text, commandHeader, globalCompletionList) {
+async function getCompletions(text, commandHeader, globalCompletionList) {
     let methods = [];
     let expr_, base;
     let attrHead = '';
@@ -29,7 +31,7 @@ function getCompletions(text, commandHeader, globalCompletionList) {
         if (matches) {
             [expr_, base, attrHead] = matches;
 
-            methods = getPropertyNamesFromExpression(base, commandHeader).filter(
+            methods = (await getPropertyNamesFromExpression(base, commandHeader)).filter(
                 attr => attr.slice(0, attrHead.length) === attrHead);
         }
 
@@ -193,13 +195,13 @@ function getAllProps(obj) {
  * @param {string} expr
  * @param {string=} commandHeader
  */
-function getPropertyNamesFromExpression(expr, commandHeader = '') {
+async function getPropertyNamesFromExpression(expr, commandHeader = '') {
     let obj = {};
     if (!isUnsafeExpression(expr)) {
         try {
-            const lines = expr.split(';');
+            const lines = expr.split('\n');
             lines.push(`return ${lines.pop()}`);
-            obj = Function(commandHeader + lines.join(';'))();
+            obj = await AsyncFunction(commandHeader + lines.join(';'))();
         } catch (e) {
             return [];
         }